package com.carleasoft.mps.adu.business.org.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carleasoft.mps.adu.business.dept.bean.po.DeptPo;
import com.carleasoft.mps.adu.business.dept.service.DeptService;
import com.carleasoft.mps.adu.business.org.bean.entity.OrgEntity;
import com.carleasoft.mps.adu.business.org.bean.entity.OrganizationType;
import com.carleasoft.mps.adu.business.org.bean.po.OrgPageQueryPo;
import com.carleasoft.mps.adu.business.org.bean.po.OrgPo;
import com.carleasoft.mps.adu.business.org.bean.vo.OrgDetailVo;
import com.carleasoft.mps.adu.business.org.dao.OrgDao;
import com.carleasoft.mps.adu.business.org.service.OrgService;
import com.carleasoft.mps.adu.common.constants.BusinessErrorEnum;
import com.carleasoft.mps.core.exceptions.BusinessException;
import com.carleasoft.mps.core.user.Constants;
import com.carleasoft.mps.core.user.SortPo;
import com.carleasoft.mps.core.utils.ConvertUtils;
import com.carleasoft.mps.core.utils.DateUtil;
import com.carleasoft.mps.security.permission.data.RequiresDataPermission;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * <p>Description: 组织 serviceImpl </p>
 *
 * @author ztm
 * @since 2020/4/28
 */
@Service
public class OrgServiceImpl extends ServiceImpl<OrgDao, OrgEntity> implements OrgService {

    @Autowired
    private DeptService deptService;

    @Autowired
    OrgDao orgDao;

    @Override
    public Page<OrgDetailVo> pageQuery(Page page, OrgPageQueryPo orgPageQueryPo) {

        return orgDao.selectOrgDetailList(page, orgPageQueryPo);

    }

    /**
     * 排序修改接口(默认顶级部门,默认顶级职务分组的排序会一并修改)
     *
     * @param sortPo
     * @return
     */
    @Override
    public Boolean updateSort(SortPo sortPo) {
        boolean result = false;
        if (sortPo.getSort() == null) {
            //自己
            OrgEntity own = this.getByCode(sortPo.getOwnCode());
            Integer ownSort = own.getSort();
            Long ownSortDate = own.getSortDate();
            if (StringUtils.isNotEmpty(sortPo.getMoveCode())) {
                OrgEntity down = this.getByCode(sortPo.getMoveCode());
                Integer downSort = down.getSort();
                Long sortDate = down.getSortDate();

                own.setSort(downSort);
                own.setSortDate(sortDate);
                down.setSort(ownSort);
                down.setSortDate(ownSortDate);
                result = this.updateById(own) && this.updateById(down);
            }
        } else {
            LambdaUpdateWrapper<OrgEntity> wrapper = Wrappers.<OrgEntity>lambdaUpdate();
            wrapper.eq(OrgEntity::getOrganizationCode, sortPo.getOwnCode());
            wrapper.set(OrgEntity::getSortDate, DateUtil.getEpochSecond());
            wrapper.set(OrgEntity::getSort, sortPo.getSort());
            result = this.update(wrapper);
        }
        return result;
    }

    // 通过编码查詢
    private OrgEntity getByCode(String code) {
        LambdaUpdateWrapper<OrgEntity> wrapper = Wrappers.<OrgEntity>lambdaUpdate();
        wrapper.eq(OrgEntity::getOrganizationCode, code);
        return this.getOne(wrapper);
    }

    /**
     * 添加组织
     *
     * @param orgPo
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public OrgEntity add(OrgPo orgPo) {
        //判断组织名称是否重复
        if (Objects.nonNull(this.getOne(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationName, orgPo.getOrganizationName())))) {
            throw new BusinessException(BusinessErrorEnum.ORG_ALREADY_EXIST);
        }
        if (orgPo.getOrganizationNumber()!=null&&Objects.nonNull(this.getOne(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationNumber, orgPo.getOrganizationNumber())))) {
            throw new BusinessException(BusinessErrorEnum.ORG_NUMBER_EXIST);
        }
        OrgEntity orgEntity = ConvertUtils.sourceToTarget(orgPo, OrgEntity.class);

        orgEntity.setOrganizationCode(IdWorker.getIdStr());

        if (orgEntity.getSort() == null || orgEntity.getSort() == 0) {
            LambdaQueryWrapper<OrgEntity> wrappers =Wrappers.lambdaQuery();
            if(StrUtil.isNotBlank(orgPo.getOrgTypeCode()))wrappers.eq(OrgEntity::getOrgTypeCode,orgPo.getOrgTypeCode());
            wrappers.orderByDesc(OrgEntity::getSort).last("limit 1");
            OrgEntity sortType = this.getOne(wrappers);
            orgEntity.setSort(Objects.isNull(sortType) ? 1 : sortType.getSort() + 1);
        }
        orgEntity.setOrganizationStatus(Constants.ENABLE);
        orgEntity.setSortDate(DateUtil.getEpochSecond());
        //创建顶级部门
        DeptPo deptPo = new DeptPo();
        deptPo.setOrganizationCode(orgEntity.getOrganizationCode());
        deptPo.setDeptName(orgEntity.getOrganizationName());
        deptPo.setDeptCode(orgEntity.getOrganizationCode());
        deptPo.setDeptNumber(orgEntity.getOrganizationNumber());
        deptPo.setSort(orgEntity.getSort());
        this.deptService.add(deptPo);
        this.save(orgEntity);
        return orgEntity;
    }

    /**
     * delete
     *
     * @param orgPo
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean deleteOrgByCode(OrgPo orgPo) {

        boolean resultDept = this.deptService.deleteDept(orgPo.getOrganizationCode());
        boolean resultOrg = this.remove(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationCode, orgPo.getOrganizationCode()));

        return resultDept || resultOrg;
    }


    /**
     * 修改组织信息
     *
     * @param orgPo
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public OrgEntity updateOrgByCode(OrgPo orgPo) {
        //判断组织名称是否重复
        OrgEntity orgEntity = this.getOne(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationCode, orgPo.getOrganizationCode()));
        if (Objects.isNull(orgEntity)) {
            throw new BusinessException(BusinessErrorEnum.ORG_NOT_EXIST);
        }

        if (this.count(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationName, orgPo.getOrganizationName()).ne(OrgEntity::getOrganizationCode,orgPo.getOrganizationCode())) > 0) {
                throw new BusinessException(BusinessErrorEnum.ORG_ALREADY_EXIST);
        }
        if (orgPo.getOrganizationNumber()!=null&&this.count(Wrappers.<OrgEntity>lambdaQuery().eq(OrgEntity::getOrganizationNumber, orgPo.getOrganizationNumber()).ne(OrgEntity::getOrganizationCode,orgPo.getOrganizationCode())) > 0) {
            throw new BusinessException(BusinessErrorEnum.ORG_NUMBER_EXIST);
        }

        orgEntity.setOrganizationName(orgPo.getOrganizationName());
        orgEntity.setOrganizationNumber(orgPo.getOrganizationNumber());
        if(StrUtil.isNotBlank(orgPo.getOrgTypeCode())&&!orgPo.getOrgTypeCode().equals(orgEntity.getOrgTypeCode())){
            orgEntity.setOrgTypeCode(orgPo.getOrgTypeCode());
            if (orgEntity.getSort() == null || orgEntity.getSort() == 0) {
                LambdaQueryWrapper<OrgEntity> wrappers =Wrappers.lambdaQuery();
                wrappers.eq(OrgEntity::getOrgTypeCode,orgPo.getOrgTypeCode());
                wrappers.orderByDesc(OrgEntity::getSort).last("limit 1");
                OrgEntity sortType = this.getOne(wrappers);
                orgEntity.setSort(Objects.isNull(sortType) ? 1 : sortType.getSort() + 1);
            }
        }
        this.saveOrUpdate(orgEntity);
        DeptPo deptPo = new DeptPo();
        deptPo.setDeptNumber(orgPo.getOrganizationNumber());
        deptPo.setDeptName(orgPo.getOrganizationName());
        deptPo.setDeptCode(orgPo.getOrganizationCode());
        deptPo.setSort(orgEntity.getSort());
        this.deptService.updateDept(deptPo);

        return orgEntity;
    }
}
